/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#include "at32f421.h"
#include "motor.h"
#include "rtthread.h"






void motor_gpio_init(void)
{
    gpio_init_type gpio_init_struct;

    /* gpioa gpiob clock enable */
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);

    gpio_init_struct.gpio_pins = GPIO_PINS_4;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOA, &gpio_init_struct);

    gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_14 | GPIO_PINS_15;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOB, &gpio_init_struct);

    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE4, GPIO_MUX_4); // PA4 -> TMR14_CH1,PWM1P
    // gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_0);//PB1 -> TMR14_CH1,PWM1N
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE14, GPIO_MUX_1); // PB14 -> TMR15_CH1,PWM2P
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE15, GPIO_MUX_1); // PB15 -> TMR15_CH2,PWM2N
}
void motor_tmr_init(void)
{
    uint16_t prescaler_value = 0;
    tmr_output_config_type tmr_oc_init_structure;
    /* tmr16 clock enable */
    crm_periph_clock_enable(CRM_TMR14_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR15_PERIPH_CLOCK, TRUE);
    /* compute the prescaler value */
    prescaler_value = (uint16_t)(system_core_clock / 24000000) - 1;

    /* tmr16 time base configuration */
    tmr_base_init(TMR14, 1000, prescaler_value);
    tmr_base_init(TMR15, 1000, prescaler_value);
    tmr_cnt_dir_set(TMR14, TMR_COUNT_UP);
    tmr_cnt_dir_set(TMR15, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR14, TMR_CLOCK_DIV1);
    tmr_clock_source_div_set(TMR15, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
    tmr_oc_init_structure.oc_idle_state = TRUE;
    tmr_output_channel_config(TMR14, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_output_channel_config(TMR15, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_output_channel_config(TMR15, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR14, TMR_SELECT_CHANNEL_1, 0);
    tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_1, 0);
    tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR14, TMR_SELECT_CHANNEL_1, TRUE);
    tmr_output_channel_buffer_enable(TMR15, TMR_SELECT_CHANNEL_1, TRUE);
    tmr_output_channel_buffer_enable(TMR15, TMR_SELECT_CHANNEL_2, TRUE);


    tmr_period_buffer_enable(TMR14, TRUE);
    tmr_period_buffer_enable(TMR15, TRUE);

}

void motor1_set_duty(int16_t duty)
{
    if(duty > 1000) duty = 1000;
    if(duty < -1000) duty = -1000;
    // rt_kprintf("m1 duty = %d\n",duty);
    if (duty > 0)
    {
        // TMR14_CH1 PWM OUTPUT AT PA4, close PB1
        gpio_bits_reset(GPIOB, GPIO_PINS_1);
        gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_4); // Close PB1

        gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE4, GPIO_MUX_4); // PA4 -> TMR14_CH1,PWM1P
        tmr_channel_value_set(TMR14, TMR_SELECT_CHANNEL_1, duty);

        tmr_output_enable(TMR14, TRUE);
        tmr_counter_enable(TMR14, TRUE);
    }
    else if (duty < 0)
    {
        // TMR14_CH1 PWM OUTPUT AT PB2, CLOSE PA4
        gpio_bits_set(GPIOA, GPIO_PINS_4);
        gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE4, GPIO_MUX_2); // Close PA4

        gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_0); // PB4 -> TMR14_CH1,PWM1N
        tmr_channel_value_set(TMR14, TMR_SELECT_CHANNEL_1, -duty);

        tmr_output_enable(TMR14, TRUE);
        tmr_counter_enable(TMR14, TRUE);
    }
    else
    {
        tmr_channel_value_set(TMR14, TMR_SELECT_CHANNEL_1, 0);
        rt_thread_mdelay(1);//wait for 0 to be written to buffer
        tmr_output_enable(TMR14, FALSE);
        tmr_counter_enable(TMR14, FALSE);

        gpio_bits_reset(GPIOA, GPIO_PINS_4);
        gpio_bits_reset(GPIOB, GPIO_PINS_1);

    }
}
void motor2_set_duty(int16_t duty)
{
    if(duty > 1000) duty = 1000;
    if(duty < -1000) duty = -1000;
    // rt_kprintf("m2 duty = %d\n",duty);
    if (duty > 0)
    {
        // TMR15_CH1 PWM OUTPUT AT PB14, close PB15
        gpio_bits_reset(GPIOB, GPIO_PINS_15);
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_1, duty);
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_2, 0);
        tmr_counter_enable(TMR15, TRUE);
        tmr_output_enable(TMR15, TRUE);

    }
    else if (duty < 0)
    {
        // TMR15_CH2 PWM OUTPUT AT PB15, close PB14
        gpio_bits_reset(GPIOB, GPIO_PINS_14);
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_2, -duty);
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_1, 0);
        tmr_counter_enable(TMR15, TRUE);
        tmr_output_enable(TMR15, TRUE);

    }
    else
    {
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_1, 0);
        tmr_channel_value_set(TMR15, TMR_SELECT_CHANNEL_2, 0);
        gpio_bits_reset(GPIOB, GPIO_PINS_14);
        gpio_bits_reset(GPIOB, GPIO_PINS_15);

        tmr_counter_enable(TMR15, FALSE);
        tmr_output_enable(TMR15, FALSE);
    }
}
/**
 * @brief
 *
 * @param mx 0~1
 * @param duty
 */
void motor_set(uint8_t mx, int16_t duty)
{
    switch (mx)
    {
    case 0:
        /* code */
        break;

    default:
        break;
    }
}
